package net.northcoding.fresh.ast;
// @Author Diamond - Administrator
// @Date 2023/12/8 10:23:36

import net.northcoding.fresh.token.Token;
import net.northcoding.fresh.util.Logger;

import java.io.IOException;
import java.util.Vector;

public abstract class AstNode {
    protected static final Logger logger = new Logger("Parser$AstNodeBuilder");
    public java.lang.String literal;
    protected Token value = null;
    protected Class<?> type = Object.class;
    protected Vector<AstNode> children = new Vector<>();
    private AstNode parent;

    public AstNode() {
    }

    public AstNode(Token value, Vector<AstNode> children, AstNode parent) {
        this.value = value;
        this.literal = value.getLiteral();

        this.children = children;
        this.parent = parent;
    }

    public final Token getValue() {
        return value;
    }

    protected final void setValue(Token value) {
        this.value = value;
    }

    public final Object getLiteral() {
        return literal;
    }

    protected final void setLiteral(java.lang.String literal) {
        this.literal = literal;
    }

    public final Vector<AstNode> getChildren() {
        return children;
    }

    protected final void setChildren(Vector<AstNode> children) {
        this.children = children;
    }

    /**
     * 执行该节点
     *
     * @return 执行结果对象:Object
     */
    public abstract Object exec();

    public final void addChild(AstNode node) {
        node.setParent(this);
        this.children.add(node);
    }

    public Object getVar(String s) throws IOException {
        return parent.getVar(s);
    }

    public void setVar(String key, Object value) {
        this.parent.setVar(key, value);
    }

    public AstNode getParent() {
        return parent;
    }

    public void setParent(AstNode parent) {
        this.parent = parent;
    }

    public String toString() {
        if (!children.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            for (AstNode child : children) {
                sb.append(child.toString());
                sb.append(',');
            }
            return "AstNode{value=%s, literal=%s, type=%s, children={%s}, parent=%s}".formatted(value, literal, type, sb.toString(), parent);
        } else {
            return "AstNode{value=%s, literal=%s, type=%s, children={}, parent=%s}".formatted(value, literal, type, parent);
        }
    }
}
